// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Vector_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Vector_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================
//
#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Vector_2_doc[] =
{
	"An object of the class Vector_2 is a vector in the two-dimensional vector space ExE.\nGeometrically spoken, a vector is the difference of two points p2, p1 and denotes the direction and the distance from p1 to p2.\n\n"\
	"CGAL defines a symbolic constant NULL_VECTOR.\nWe will explicitly state where you can pass this constant as an argument instead of a vector initialized with zeros. .\n",
	"x(self) -> returns the Cartesian  x coordinate, that is hx/hw.\n",
	"y(self) -> returns the Cartesian  y coordinate, that is hy/hw.\n",
	"hx(self) -> returns the homogeneous x coordinate.\n",
	"hy(self) -> returns the homogeneous y coordinate.\n",
	"hw(self) -> returns the homogenizing coordinate.\n",
	"dimension(self) -> returns the dimension (the constant 2).\n",
	"homogeneous(self,i) -> returns the i'th homogeneous coordinate of v,starting with 0.Precondition: 0 <= i <= 2.\n",
	"direction(self) ->  returns the direction which passes through v.\n"\
	"Note that bounding boxes are not parameterized with whatsoever.\n",
	"v[i] -> returns cartesian(i).Precondition: 0 <= i <= 1.\n",
	"cartesian(self,i) -> returns the i'th Cartesian  coordinate of v, starting with 0.\nPrecondition: 0 <= i <= 1.\n",
	"transform(self,Aff_transformation_2<Kernel> t) -> returns the point obtained by applying t on v.\n",
	"perpendicular(self,Orientation o) -> returns the vector perpendicular to v in clockwise or counterclockwise orientation.\n"
};

template<class Vector_2>
boost::python::str py_repr_Vector_2(const Vector_2& v )
{
	using namespace boost::python;
	return str("Vector_2("+ str(v.x()) +","+ str(v.y()) +")" );
}

template<class kernel>
void Py_Vector_2()
{
	typedef typename kernel::Point_2 					Point_2;
	typedef typename kernel::Segment_2 					Segment_2;
 	typedef typename kernel::Vector_2 					Vector_2;
 	typedef typename kernel::Direction_2 					Direction_2;
 	typedef typename kernel::Line_2 					Line_2;
  	typedef typename kernel::Ray_2 					        Ray_2;
 	typedef typename kernel::Triangle_2 					Triangle_2;
	typedef typename kernel::Iso_rectangle_2 				Iso_rectangle_2;
	typedef typename kernel::Circle_2 				      	Circle_2;
	typedef typename kernel::Aff_transformation_2 				Aff_transformation_2;
	typedef typename kernel::FT 						FT;
	typedef typename kernel::RT						RT;

	using namespace boost::python;

        class_< Vector_2 >("Vector_2", Vector_2_doc[0], init<>())
        .def(init< const Vector_2& >())
        .def(init< const Point_2&, const Point_2& >())
        .def(init< const Segment_2& >())
        .def(init< const Ray_2& >())
        .def(init< const Line_2& >())
        .def(init< const CGAL::Null_vector& >())
        .def(init< const FT&, const FT& >())
        .def(init< const FT&, const FT&, const FT& >())

        .def(init< const double&, const double& >())
        .def(init< const double&, const double&, const double& >())

#if CGAL_VERSION_NR < 1030301000
        .def("x", &Vector_2::x, by_cref(), Vector_2_doc[1])
        .def("y", &Vector_2::y, by_cref(), Vector_2_doc[2])
        .def("cartesian", &Vector_2::cartesian, by_cref(), Vector_2_doc[10])
        .def("hx", &Vector_2::hx, by_cref(), Vector_2_doc[3])
        .def("hy", &Vector_2::hy, by_cref(), Vector_2_doc[4])
        .def("hw", &Vector_2::hw, by_cref(), Vector_2_doc[5])
        .def("homogeneous", &Vector_2::homogeneous, by_cref(), Vector_2_doc[7])
#else
        .def("x", &Vector_2::x, typename Value_or_cref<typename kernel::Compute_x_2, Vector_2 > ::type(), Vector_2_doc[1])
        .def("y", &Vector_2::y, typename Value_or_cref<typename kernel::Compute_y_2, Vector_2 > ::type(), Vector_2_doc[2])
        .def("cartesian", &Vector_2::cartesian, typename Value_or_cref<typename kernel::Compute_x_2, Vector_2 > ::type(), Vector_2_doc[10])
        .def("hx", &Vector_2::hx, typename Value_or_cref<typename kernel::Compute_hx_2, Vector_2 > ::type(), Vector_2_doc[3])
        .def("hy", &Vector_2::hy, typename Value_or_cref<typename kernel::Compute_hy_2, Vector_2 > ::type(), Vector_2_doc[4])
        .def("hw", &Vector_2::hw, typename Value_or_cref<typename kernel::Compute_hw_2, Vector_2 > ::type(), Vector_2_doc[5])
        .def("homogeneous", &Vector_2::homogeneous, typename Value_or_cref<typename kernel::Compute_hx_2, Vector_2 > ::type(), Vector_2_doc[7])
#endif
        .def("dimension", &Vector_2::dimension, Vector_2_doc[6])
        .def("squared_length", &Vector_2::squared_length)
        .def("direction", &Vector_2::direction, Vector_2_doc[8])
        .def("perpendicular", &Vector_2::perpendicular, Vector_2_doc[12])
#if CGAL_VERSION_NR < 1030301000
	.def("__getitem__", &Vector_2::operator[], by_cref(), Vector_2_doc[9])
#else
	.def("__getitem__", &Vector_2::operator[], typename Value_or_cref<typename kernel::Compute_x_2, Vector_2 > ::type(), Vector_2_doc[9])
#endif
	.def("__repr__", &py_repr_Vector_2<Vector_2>)
	.def("transform", &Vector_2::transform, Vector_2_doc[11])
	.def(self == self)
	.def(self != self)
        .def( -self )
        .def( self - self )
        .def( self + self )
	.def( self * self )
	.def( self * double() )
	.def( double() * self)
        .def( self / double() )
        .def( CGAL::Origin() + self )
    ;
}


void export_Vector_2()
{
	Py_Vector_2<K>();
}
